package com.panda.admin.login.access.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.panda.admin.base.BaseEnum;
import com.panda.admin.login.dto.RoleMenusDto;
import com.panda.admin.login.entity.SystemMenu;
import com.panda.admin.login.entity.SystemRoleMenu;
import com.panda.admin.login.access.service.SystemMenuService;
import com.panda.admin.login.access.mapper.SystemMenuMapper;
import com.panda.admin.login.access.service.SystemRoleMenuService;
import com.panda.admin.login.enums.MenuTypeEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
* @author tucy123
* @description 针对表【system_menu(商城菜单表)】的数据库操作Service实现
* @createDate 2023-05-11 13:44:14
*/
@Service
public class SystemMenuServiceImpl extends ServiceImpl<SystemMenuMapper, SystemMenu> implements SystemMenuService{

    @Autowired
    SystemMenuMapper systemMenuMapper;

    @Autowired
    SystemRoleMenuService systemRoleMenuService;

    /**
     * 查询全部菜单
     * @return
     */
    @Override
    public List<SystemMenu> queryMenus() {
        //查询全部菜单
        List<SystemMenu> menus = this.lambdaQuery().orderByAsc(SystemMenu::getSort).list();

        for (SystemMenu menu : menus) {
            if (menu.getParentId() != 0){
                SystemMenu filterMenu = menus.stream().filter(systemMenu -> systemMenu.getId().equals(menu.getParentId())).collect(Collectors.toList()).get(0);
                menu.setParentName(filterMenu.getMenuName());
            }
        }

        return menus;
        //筛选父菜单，子菜单放其下
//        return menus.stream().filter(menu -> menu.getParentId() == 0)
//                .peek(parentMenu -> parentMenu.setChild(getMenuChild(parentMenu, menus)))
//                .sorted(Comparator.comparing(SystemMenu::getSort))
//                .collect(Collectors.toList());
    }

    /**
     * 查询目录菜单
     * @return
     */
    @Override
    public List<SystemMenu> queryMenuAndDirect() {
        List<SystemMenu> systemMenus = this.lambdaQuery().in(SystemMenu::getType, 0, 1).orderByAsc(SystemMenu::getSort).list();
        SystemMenu menu = new SystemMenu();
        menu.setId(0L);
        menu.setMenuName("根目录");
        menu.setParentId(-1L);
        menu.setSort(-1);
        systemMenus.add(menu);
        return systemMenus;
    }

    /**
     * 根据id查询菜单详情
     * @param id
     * @return
     */
    @Override
    public SystemMenu queryMenuById(Long id) {
        return systemMenuMapper.selectById(id);
    }

    /**
     * 增改菜单
     * @param systemMenu
     * @return
     */
    @Override
    public Boolean saveOrUpdateMenus(SystemMenu systemMenu) {
        //修改菜单
        if (ObjectUtil.isNotEmpty(systemMenu.getId())){
            return this.updateById(systemMenu);
        }
        if (ObjectUtil.isEmpty(systemMenu.getParentId())){
            systemMenu.setParentId(Long.valueOf(BaseEnum.DELETE.getValue()));
        }
        Integer countMenus = systemMenuMapper.countMenus(systemMenu.getParentId());
        systemMenu.setSort(countMenus);
        return this.saveOrUpdate(systemMenu);
    }

    /**
     * 删除菜单
     * @param id
     * @return
     */
    @Override
    public Boolean deleteMenus(Long id) {
        List<SystemMenu> menuList = new LinkedList<>();
        SystemMenu menu = systemMenuMapper.selectById(id);
        Integer menuType = menu.getType();

        if (MenuTypeEnum.BUTTON.getValue().equals(menuType)){
            int i = systemMenuMapper.deleteById(menu);
            return i != 0;
        } else if (MenuTypeEnum.MENU.getValue().equals(menuType)){
            List<SystemMenu> systemMenus = this.lambdaQuery().eq(SystemMenu::getParentId, id).list();
            menuList.add(menu);
            menuList.addAll(systemMenus);
            int i = systemMenuMapper.deleteBatchIds(menuList);
            return i != 0;
        } else {
            List<SystemMenu> allMenus = this.list();
            List<SystemMenu> deleteMenus = allMenus.stream().filter(systemMenu -> systemMenu.getParentId().equals(id)).collect(Collectors.toList());
            for (SystemMenu deleteMenu : deleteMenus) {
                List<SystemMenu> deleteButton = allMenus.stream().filter(systemMenu -> systemMenu.getParentId().equals(deleteMenu.getId())).collect(Collectors.toList());
                menuList.addAll(deleteButton);
            }
            menuList.add(menu);
            menuList.addAll(deleteMenus);
            int i = systemMenuMapper.deleteBatchIds(menuList);
            return i != 0;
        }
    }

    /**
     * 根据角色查询菜单
     * @param roleId
     * @return
     */
    @Override
    public RoleMenusDto queryMenusByRole(Long roleId) {
        RoleMenusDto result = new RoleMenusDto();

        //查询角色权限菜单
        List<SystemRoleMenu> roleMenus = systemRoleMenuService.lambdaQuery().eq(SystemRoleMenu::getRoleId, roleId).list();

        if (ObjectUtil.isNotEmpty(roleMenus)){
            List<Long> menuIds = roleMenus.stream().map(SystemRoleMenu::getMenuId).collect(Collectors.toList());
            List<SystemMenu> menus = this.lambdaQuery().in(SystemMenu::getId,menuIds).in(SystemMenu::getType,0,1).list();

            //筛选父菜单，子菜单放其下
            List<SystemMenu> systemMenus = menus.stream().filter(menu -> menu.getParentId() == 0)
                                           .peek(parentMenu -> parentMenu.setChild(getMenuChild(parentMenu, menus)))
                                           .sorted(Comparator.comparing(SystemMenu::getSort))
                                           .collect(Collectors.toList());

            //查询按钮授权
            List<SystemMenu> permMenus = this.lambdaQuery().in(SystemMenu::getId, menuIds).eq(SystemMenu::getType, 2).list();
            List<String> perms = permMenus.stream().map(SystemMenu::getPerms).collect(Collectors.toList());

            result.setSystemMenus(systemMenus);
            result.setPerms(perms);
            return result;
        } else {
            return null;
        }
    }

    private List<SystemMenu> getMenuChild(SystemMenu parentMenu, List<SystemMenu> menus) {
        return menus.stream().filter(childMenu -> childMenu.getParentId().equals(parentMenu.getId()))
                .peek(childMenu -> childMenu.setChild(getMenuChild(childMenu,menus)))
                .sorted(Comparator.comparing(SystemMenu::getSort))
                .collect(Collectors.toList());
    }
}
